#include <iostream>
#include <cerrno> // C++包C语言头文件常用的方法,和.h效果一样
#include <cstring>
#include <cassert>
#include <unistd.h> // pipe + close + read + write
#include <sys/types.h> // waitpid两个头文件
#include <sys/wait.h>
#include <signal.h>

using namespace std;

void catchSig(int signum)
{
    cout << "进程捕捉到了一个信号,正在处理中: " << signum << " Pid: " << getpid() << endl;
}

int main()
{
    int pipefd[2];
    int ret = pipe(pipefd); // 一.创建管道
    if(ret < 0)
    {
        cerr << errno << ": " << strerror(errno) << endl;
    }

    pid_t id = fork(); // 二.创建子进程
    assert(id != -1);
    if (id == 0) // 子进程，读，关闭写
    {
        close(pipefd[1]);
        // 三. 子进程读
        int cnt = 0;
        while (true)
        {
            char buffer[1024];
            ssize_t s = read(pipefd[0], buffer, sizeof(buffer) - 1); // read读

            cout << "我是子进程,我的pid: " << getpid()<< endl;

            if(++cnt == 5) // 5秒后关闭读端
            {
                close(pipefd[0]);
                cout << "读端关闭" << endl;
                exit(0);
            }
            sleep(1);
        }
    }

    signal(SIGPIPE, catchSig); // 特定信号的处理动作,一般只有一个

    close(pipefd[0]); // 父进程，写，关闭读
    // 四. 父进程写
    const char* send_buffer = "这是一条信息";
    while (true)
    {
        cout << "我是父进程,我的pid: " << getpid()<< endl;
        ssize_t s = write(pipefd[1], send_buffer, strlen(send_buffer));
        sleep(1); // 父进程一直写，不关闭写端
    }
    return 0;
}